package com.miya.demo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.miya.demo.common.constant.CommonConstant;
import com.miya.demo.common.util.Assert;
import com.miya.demo.entity.RoleMenu;
import com.miya.demo.entity.UserRole;
import com.miya.demo.model.dto.system.RoleAddOrUpdateDTO;
import com.miya.demo.service.RoleMenuService;
import com.miya.demo.service.UserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.miya.demo.mapper.RoleMapper;
import com.miya.demo.entity.Role;
import com.miya.demo.service.RoleService;
import org.springframework.transaction.annotation.Transactional;

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private RoleMenuService roleMenuService;

    /**
     * 新增/编辑角色
     *
     * @param roleDTO 角色dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrUpdate(RoleAddOrUpdateDTO roleDTO) {
        Long id = roleDTO.getId();
        Role role = null;
        if (id == null) {
            // 新增
            role = this.lambdaQuery()
                    .eq(Role::getRoleName, roleDTO.getRoleName())
                    .last(CommonConstant.SQL_LIMIT_ONE)
                    .one();
            Assert.isNull(role, "角色名称已存在。");
            role = new Role();
        } else {
            // 编辑
            role = this.getById(id);
            Assert.notNull(role, "角色不存在。");
            // 删除已存在角色资源信息
            LambdaUpdateWrapper<RoleMenu> updateWrapper = Wrappers.lambdaUpdate(RoleMenu.class)
                    .eq(RoleMenu::getRoleId, id);
            roleMenuService.remove(updateWrapper);
        }
        BeanUtil.copyProperties(roleDTO, role, CopyOptions.create().ignoreNullValue());
        this.saveOrUpdate(role);

        if (CollUtil.isNotEmpty(roleDTO.getMenuIds())) {
            List<RoleMenu> roleMenus = CollUtil.newArrayList();
            for (Long menuId : roleDTO.getMenuIds()) {
                roleMenus.add(new RoleMenu(role.getId(), menuId));
            }
            roleMenuService.saveBatch(roleMenus);
        }
    }

    @Override
    public List<Role> getByUserId(Long userId) {
        List<UserRole> list = userRoleService.lambdaQuery()
                .eq(UserRole::getUserId, userId)
                .list();
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        List<Long> roleIds = list.stream().map(UserRole::getRoleId).collect(Collectors.toList());
        List<Role> roles = this.lambdaQuery()
                .in(Role::getId, roleIds)
                .list();
        if (CollUtil.isEmpty(roles)) {
            return Collections.emptyList();
        }
        return roles;
    }
}

